#pragma once
#include <string>
#include <cstddef> // std::size_t
#include <boost/date_time/posix_time/posix_time.hpp>
#include <odb/nullable.hxx>
#include <odb/core.hxx>

#pragma db object table("tbl_student")
class Student {
    public:
        Student() {}
        Student(const std::string &name): _name(name) {}
        size_t sn() const { return _sn; }
        void set_sn(size_t sn) { _sn = sn; }
        const std::string &name() const { return _name; }
        void set_name(const std::string &name) { _name = name; }
        odb::nullable<int> age() const { return _age; }
        void set_age(odb::nullable<int> age) { _age = age; }
        odb::nullable<double> score() const { return _score; }
        void set_score(odb::nullable<double> score) { _score = score; }
        odb::nullable<boost::posix_time::ptime> birthday() const { return _birthday; }
        void set_birthday(const boost::posix_time::ptime &birthday) { _birthday = birthday; }
    private:
    //odb::access 是 ODB 内部类，声明为友元以让 ODB 访问私有成员（用于数据库操作）
        friend class odb::access;
        #pragma db id auto//声明 _sn 为数据库表的主键  auto自增主键
        size_t _sn;//射到表 tbl_student 的 _sn 字段（类型为整数，自增）
        
        #pragma db index//为 _classes_id 字段创建数据库索引（加速查询）
        size_t _classes_id;//该字段表示学生所属班级的 ID，用于与 Classes 类
        //（班级表）关联（外键逻辑，这里通过字段关联，未显式声明外键约束）
        
        std::string _name;
        odb::nullable<int> _age;
        odb::nullable<double> _score;
        odb::nullable<boost::posix_time::ptime> _birthday;
};


//班级类（Classes）映射到数据库表 tbl_classes
#pragma db object table("tbl_classes")
class Classes {
public:
    Classes() {}
    Classes(const std::string &name):_name(name) {}
    size_t id() const {return _id; }
    void set_id(size_t id) { _id = id; }
    const std::string &name() const { return _name; }
    void set_name(const std::string &name) { _name = name; }

//私有成员变量（映射到数据库字段
private:
    friend class odb::access;

    #pragma db id auto
    size_t _id;//_id 是班级表的自增主键，映射到 tbl_classes 的 _id 字段

    //声明班级名称唯一
    #pragma db unique type("VARCHAR(32)")//显式指定数据库字段类型为 VARCHAR(32)
    std::string _name;
};


//视图 ClassesStudent（关联查询：按班级查学生）
// 过滤条件： Query::Classes::name == "一年级一班" 

//声明该结构体为 ODB 视图（用于关联查询，不映射到表，仅用于查询结果封装）
#pragma db view object(Classes) \
                object(Student : Student::_classes_id == Classes::_id) \
                query((?))
struct ClassesStudent {
    std::shared_ptr<Student> student;
    std::shared_ptr<Classes> classes;
};

//视图 DetailStudent（关联查询：按学生查班级）
// 过滤条件： Query::Student::name == "zhangsan" 
#pragma db view object(Student) \
                object(Classes : Student::_classes_id == Classes::_id) \
                query((?))
//query((?)) 占位符需传入学生相关条件
struct DetailStudent {
    std::shared_ptr<Student> student;
    std::shared_ptr<Classes> classes;
};



